#pragma once
#include <cstring>
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string>
#include <cstdio>
#include <sys/shm.h>
#include <unistd.h>
#include "time.hpp"
const std::string path = "./";
int projectId = 0x6666;
// zdl:: 操作系统，申请空间，是按照块为单位 4kb 1kb 2kb 4MB
int gsize = 4096;
mode_t gmod = 0600;

std::string toHex(key_t k)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "%0x", k);
    return buffer;
}

class sharedMemory
{
private:
    key_t _key;
    int _shmid;
    void *_addr;

    int createShmHelper(int shmflg)
    {
        _key = ::ftok(path.c_str(), projectId);
        if (_key < 0)
        {
            std::cerr << "ftok error" << std::endl;
            return -1;
        }
        _shmid = ::shmget(_key, gsize, shmflg);
        if (_shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return -1;
        }
        std::cout << "shmget success and shmid: " << _shmid << std::endl;
        std::cout << "key: " << toHex(_key) << std::endl;

        return _shmid;
    }

public:
    sharedMemory(/* args */);
    ~sharedMemory();
    void createShm()
    {
        if (_shmid < 0)
            createShmHelper(IPC_CREAT | IPC_EXCL | gmod);
    }
    void getShm()
    {
        createShmHelper(IPC_CREAT);
    }
    void attachShm()
    {
        _addr = shmat(_shmid, nullptr, 0);
        if ((long long)_addr == -1)
        {
            std::cout << "attach error" << std::endl;
            return;
        }

        // return _addr;
    }
    void detachShm()
    {
        if (_addr != nullptr)
            ::shmdt(_addr);
    }
    void deleteShm()
    {
        shmctl(_shmid, IPC_RMID, NULL);
    }
    void shmMeta()
    {
        struct shmid_ds buffer; // 系统提供的数据类型
        int n = ::shmctl(_shmid, IPC_STAT, &buffer);
        if (n < 0)
            return;
        std::cout << buffer.shm_cpid << std::endl;
        std::cout << buffer.shm_perm.__key << std::endl;
        std::cout << buffer.shm_segsz << std::endl;
        std::cout << buffer.shm_nattch << std::endl;
        std::cout << buffer.shm_ctime << std::endl;
    }

    void *getAddr()
    {
        return _addr;
    }
};

sharedMemory::sharedMemory() : _shmid(-1), _addr(nullptr)
{
}

sharedMemory::~sharedMemory()
{
}

sharedMemory shm;

struct data
{

    char status[32];
    char lasttimme[48];
    char image[1024];
};
